package cn.bluarry.downloaddemo;

import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class DownLoadTask extends AsyncTask<String,Integer,Integer> {

    public static final int TYPE_SUCCESS=1;
    public static final int TYPE_FAILD=2;
    public static final int TYPE_PAUSED=3;
    public static final int TYPE_CANCEL=4;

    private DownLoadListener downLoadListener;

    private boolean isCanceled=false;

    private boolean isPaused=false;

    private int lastProgress;

    public DownLoadTask(DownLoadListener listener){
        downLoadListener=listener;
    }

    public void PauseDownload(){
        isPaused=true;
    }

    public void CancelDownload(){
        isCanceled=true;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        int p=values[0];
        if(p > lastProgress){
            downLoadListener.onProgress(p);
            lastProgress=p;
        }
    }

    @Override
    protected void onPostExecute(Integer integer) {
        switch (integer){
            case TYPE_CANCEL:
                downLoadListener.onCanceled();
                break;
            case TYPE_FAILD:
                downLoadListener.onFaild();
                break;
            case TYPE_PAUSED:
                downLoadListener.onPause();
                break;
            case TYPE_SUCCESS:
                downLoadListener.onSuccess();
                break;
            default:
                break;
        }
    }

    private long getContentLength(String downloadUrl) throws IOException {
        OkHttpClient client=new OkHttpClient();
        Request request=new Request.Builder().url(downloadUrl).build();
        Response response=client.newCall(request).execute();
        if(response!=null && response.isSuccessful()){
            long l=response.body().contentLength();
            response.close();
            return l;
        }
        return  0;
    }
    @Override
    protected Integer doInBackground(String... strings) {
        InputStream is=null;
        RandomAccessFile savedFile=null;
        File file=null;
        try {
            long downLoadLength=0;
            String DownLoadUrl=strings[0];
            String filename=DownLoadUrl.substring(DownLoadUrl.lastIndexOf("/"));
            String directory= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
            file =new File(directory+filename);
            if(file.exists()){
                downLoadLength=file.length();
            }
            long contentlength=getContentLength(DownLoadUrl);
            if(contentlength==0){
                return TYPE_FAILD;
            }else if(contentlength==downLoadLength){
                return TYPE_SUCCESS;
            }
            OkHttpClient client=new OkHttpClient();
            Request request=new Request.Builder()
                    .addHeader("RANGE","bytes="+downLoadLength+"-")
                    .url(DownLoadUrl)
                    .build();
            Response response=client.newCall(request).execute();
            if(response!=null){
                is=response.body().byteStream();
                savedFile=new RandomAccessFile(file,"rw");
                savedFile.seek(downLoadLength);
                byte[] b=new byte[1024];
                int total=0;
                int len;
                while( (len=is.read(b)) !=-1){
                    if(isCanceled){
                        return TYPE_CANCEL;
                    }else if(isPaused){
                        return TYPE_PAUSED;
                    }else{
                        total+=len;
                        savedFile.write(b,0,len);
                        int progress= (int)((total+downLoadLength)*100/contentlength);
                        publishProgress(progress);
                    }
                }
            }

            response.close();
            return TYPE_SUCCESS;
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(is!=null){
                        is.close();
                }
                if(savedFile!=null){
                    savedFile.close();
                }
                if(isCanceled && file!=null){
                    file.delete();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return TYPE_FAILD;
    }
}
